<template>
  <div class="file-selector-wrapper">
    <!-- 触发按钮 -->
    <el-button @click="showSelector" :disabled="disabled">
      <el-icon><FolderOpened /></el-icon>
      {{ buttonText || '选择文件' }}
    </el-button>

    <!-- 已选择的文件预览 -->
    <div v-if="modelValue" class="selected-files">
      <div v-if="fileType === 'image'" class="image-preview">
        <img :src="getImageUrl(modelValue)" :alt="alt" />
        <el-button size="small" type="danger" @click="removeFile">
          <el-icon><Delete /></el-icon>
        </el-button>
      </div>
      <div v-else class="file-preview">
        <el-icon><Document /></el-icon>
        <span>{{ getFileName(modelValue) }}</span>
        <el-button size="small" type="danger" @click="removeFile">
          <el-icon><Delete /></el-icon>
        </el-button>
      </div>
    </div>

    <!-- 文件选择对话框 -->
    <el-dialog
      v-model="selectorVisible"
      :title="dialogTitle"
      width="80%"
      :close-on-click-modal="false"
    >
      <div class="file-selector-content">
        <!-- 搜索和筛选 -->
        <div class="selector-header">
          <el-input
            v-model="searchKeyword"
            placeholder="搜索文件名"
            style="width: 300px"
            @input="handleSearch"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
          
          <el-select v-model="fileTypeFilter" placeholder="文件类型" style="width: 150px" @change="handleFilter">
            <el-option label="全部" value="" />
            <el-option label="图片" value="image" />
            <el-option label="文档" value="document" />
            <el-option label="视频" value="video" />
            <el-option label="音频" value="audio" />
          </el-select>
        </div>

        <!-- 文件列表 -->
        <div class="file-list" v-loading="loading">
          <div v-if="fileType === 'image'" class="image-grid">
            <div
              v-for="file in filteredFiles"
              :key="file.id"
              class="image-item"
              :class="{ active: selectedFile?.id === file.id }"
              @click="selectFile(file)"
            >
              <img :src="getImageUrl(file.url)" :alt="file.name" />
              <div class="image-info">
                <div class="image-name">{{ file.name }}</div>
                <div class="image-size">{{ formatFileSize(file.size) }}</div>
              </div>
            </div>
          </div>
          
          <div v-else class="file-table">
            <el-table
              :data="filteredFiles"
              @row-click="selectFile"
              highlight-current-row
            >
              <el-table-column type="selection" width="55" />
              <el-table-column prop="name" label="文件名" min-width="200" />
              <el-table-column prop="type" label="类型" width="100" />
              <el-table-column prop="size" label="大小" width="100">
                <template #default="{ row }">
                  {{ formatFileSize(row.size) }}
                </template>
              </el-table-column>
              <el-table-column prop="createTime" label="上传时间" width="180" />
            </el-table>
          </div>

          <!-- 空状态 -->
          <div v-if="!loading && filteredFiles.length === 0" class="empty-state">
            <el-empty description="暂无文件" />
          </div>
        </div>

        <!-- 分页 -->
        <div class="pagination-wrapper">
          <el-pagination
            v-model:current-page="pagination.current"
            v-model:page-size="pagination.size"
            :total="pagination.total"
            :page-sizes="[12, 24, 48, 96]"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="selectorVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmSelect" :disabled="!selectedFile">
            确定选择
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { FolderOpened, Delete, Document, Search } from '@element-plus/icons-vue'

// 组件名称
defineOptions({
  name: 'FileSelector'
})

// Props
interface Props {
  modelValue?: string
  fileType?: 'image' | 'file'
  buttonText?: string
  dialogTitle?: string
  alt?: string
  disabled?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  fileType: 'image',
  dialogTitle: '选择文件',
  disabled: false
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: string]
  'change': [value: string]
}>()

// 响应式数据
const selectorVisible = ref(false)
const loading = ref(false)
const searchKeyword = ref('')
const fileTypeFilter = ref('')
const selectedFile = ref<any>(null)

// 文件列表和分页
const fileList = ref<any[]>([])
const pagination = ref({
  current: 1,
  size: props.fileType === 'image' ? 24 : 20,
  total: 0
})

// 计算属性
const filteredFiles = computed(() => {
  let files = fileList.value
  
  // 搜索过滤
  if (searchKeyword.value) {
    files = files.filter(file => 
      file.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
    )
  }
  
  // 类型过滤
  if (fileTypeFilter.value) {
    files = files.filter(file => file.type === fileTypeFilter.value)
  }
  
  return files
})

// 获取完整图片URL
const getImageUrl = (url: string) => {
  if (!url) return ''
  if (url.startsWith('http')) return url
  return `${import.meta.env.VITE_API_BASE_URL}${url}`
}

// 获取文件名
const getFileName = (url: string) => {
  if (!url) return ''
  return url.split('/').pop() || ''
}

// 格式化文件大小
const formatFileSize = (size: number) => {
  if (size < 1024) return size + ' B'
  if (size < 1024 * 1024) return (size / 1024).toFixed(1) + ' KB'
  return (size / (1024 * 1024)).toFixed(1) + ' MB'
}

// 显示选择器
const showSelector = () => {
  selectorVisible.value = true
  loadFiles()
}

// 加载文件列表
const loadFiles = async () => {
  loading.value = true
  try {
    // 这里调用实际的API获取文件列表
    // const response = await fileApi.getList({
    //   page: pagination.value.current,
    //   size: pagination.value.size,
    //   type: props.fileType
    // })
    
    // 模拟数据
    const mockFiles = [
      {
        id: 1,
        name: 'example1.jpg',
        url: '/uploads/example1.jpg',
        type: 'image',
        size: 1024000,
        createTime: '2024-01-01 12:00:00'
      },
      {
        id: 2,
        name: 'example2.jpg',
        url: '/uploads/example2.jpg',
        type: 'image',
        size: 2048000,
        createTime: '2024-01-02 12:00:00'
      }
    ]
    
    fileList.value = mockFiles
    pagination.value.total = mockFiles.length
  } catch (error) {
    console.error('Failed to load files:', error)
    ElMessage.error('加载文件列表失败')
  } finally {
    loading.value = false
  }
}

// 选择文件
const selectFile = (file: any) => {
  selectedFile.value = file
}

// 确认选择
const confirmSelect = () => {
  if (selectedFile.value) {
    emit('update:modelValue', selectedFile.value.url)
    emit('change', selectedFile.value.url)
    selectorVisible.value = false
    selectedFile.value = null
    ElMessage.success('文件选择成功')
  }
}

// 移除文件
const removeFile = () => {
  emit('update:modelValue', '')
  emit('change', '')
}

// 搜索处理
const handleSearch = () => {
  // 搜索逻辑已在计算属性中处理
}

// 筛选处理
const handleFilter = () => {
  // 筛选逻辑已在计算属性中处理
}

// 分页处理
const handleSizeChange = () => {
  loadFiles()
}

const handleCurrentChange = () => {
  loadFiles()
}

// 暴露方法给父组件
defineExpose({
  showSelector
})
</script>

<style scoped lang="scss">
.file-selector-wrapper {
  .selected-files {
    margin-top: 8px;

    .image-preview {
      position: relative;
      display: inline-block;

      img {
        width: 100px;
        height: 100px;
        object-fit: cover;
        border-radius: 4px;
        border: 1px solid #dcdfe6;
      }

      .el-button {
        position: absolute;
        top: -8px;
        right: -8px;
        border-radius: 50%;
        width: 24px;
        height: 24px;
        padding: 0;
      }
    }

    .file-preview {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 8px;
      border: 1px solid #dcdfe6;
      border-radius: 4px;
      background: #f5f7fa;
    }
  }

  .file-selector-content {
    .selector-header {
      display: flex;
      gap: 16px;
      margin-bottom: 16px;
    }

    .file-list {
      min-height: 400px;
      margin-bottom: 16px;

      .image-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 16px;

        .image-item {
          border: 2px solid transparent;
          border-radius: 8px;
          overflow: hidden;
          cursor: pointer;
          transition: all 0.3s;

          &:hover {
            border-color: #409eff;
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
          }

          &.active {
            border-color: #409eff;
            box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
          }

          img {
            width: 100%;
            height: 120px;
            object-fit: cover;
          }

          .image-info {
            padding: 8px;
            background: white;

            .image-name {
              font-size: 12px;
              color: #303133;
              margin-bottom: 4px;
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
            }

            .image-size {
              font-size: 11px;
              color: #909399;
            }
          }
        }
      }

      .file-table {
        :deep(.el-table__row) {
          cursor: pointer;
        }
      }

      .empty-state {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 200px;
      }
    }

    .pagination-wrapper {
      display: flex;
      justify-content: center;
    }
  }
}
</style>
